package com.example.cadmin.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.cadmin.entity.*;
import com.example.cadmin.mapper.ArchivesMapper;
import com.example.cadmin.mapper.BorrowingRecordsMapper;
import com.example.cadmin.security.dto.JwtUserDto;
import com.example.cadmin.service.ArchivesService;
import com.example.cadmin.service.FileLogService;
import com.example.cadmin.service.HostService;
import com.example.cadmin.service.MyUserService;
import com.example.cadmin.utils.CalculateMonth;
import com.example.cadmin.utils.DateFormat;
import com.example.cadmin.utils.Netty.sendCmd;
import com.example.cadmin.utils.ResponseModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * <p>
 * 主页-控制器
 * </p>
 *
 * @author 张彬
 * @since 2022-08-20
 */
@Slf4j
@Controller
@RequestMapping("")
public class IndexController {
    @Resource
    private HostService hostService;
    @Resource
    private ArchivesService archivesService;
    @Resource
    public sendCmd sendCmd;
    @Resource
    public BorrowingRecordsMapper borrowingRecordsMapper;
    @Resource
    public ArchivesMapper archivesMapper;
    @Resource
    public MyUserService myUserService;

    @GetMapping("")
    public ModelAndView index(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        List<Map<String, Object>> hostList = hostService.listMaps();
//        modelAndView.addObject("hostList", hostList);
        HttpSession session = request.getSession();
        session.setAttribute("cabinet", hostList.get(0).get("ip"));
        session.setAttribute("number", hostList.get(0).get("number"));
        // 获取用户信息
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userName = jwtUserDto.getUsername();
        modelAndView.addObject("userName", userName);
        return modelAndView;
    }

    @GetMapping("index")
    public ModelAndView indexHref(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        List<Map<String, Object>> hostList = hostService.listMaps();
        modelAndView.addObject("hostList", hostList);
        HttpSession session = request.getSession();
        session.setAttribute("cabinet", hostList.get(0).get("ip"));
        session.setAttribute("number", hostList.get(0).get("number"));
        // 获取用户信息
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userName = jwtUserDto.getUsername();
        modelAndView.addObject("userName", userName);
        return modelAndView;
    }

    @GetMapping("/403")
    public String error403() {
        return "error/403";
    }

    @GetMapping("/404")
    public String error404() {
        return "error/404";
    }

    @GetMapping("/500")
    public String error500() {
        return "error/500";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    /**
     * 主页
     */
    @GetMapping("console")
    public ModelAndView console(HttpServletRequest request) throws IOException {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("console/console1");
        List<Archives> archivesList = archivesService.list();
        int inTheLibrary = 0;
        int borrowCount = 0;
        for (Archives archives : archivesList) {
            if (archives.getStatus() == 1) {
                borrowCount += 1;
            } else if (archives.getStatus() == 0) {
                inTheLibrary += 1;
            }
        }
        modelAndView.addObject("inTheLibrary", inTheLibrary);
        modelAndView.addObject("borrowCount", borrowCount);
        modelAndView.addObject("archivesCount", archivesList.size());
        //总的用户数量
        int myUserCount = myUserService.count(new QueryWrapper<MyUser>().eq("status", 1));
        modelAndView.addObject("myUserCount", myUserCount);
        // 机柜数量
        int cabinetCount = hostService.count();
        modelAndView.addObject("cabinetCount", cabinetCount);
        // 库区信息饼状图
        List<Map<String, Object>> overviewPieDataList = new ArrayList<>();
        Map<String, Object> quantityMapInTheLibrary = new HashMap<>();
        quantityMapInTheLibrary.put("name", "在库数量");
        quantityMapInTheLibrary.put("value", inTheLibrary);
        overviewPieDataList.add(quantityMapInTheLibrary);
        if (borrowCount != 0 && !archivesList.isEmpty()) {
            BigDecimal inTheLibraryPercent = NumberUtil.round((double) inTheLibrary / archivesList.size() * 100, 2);
            modelAndView.addObject("inTheLibraryPercent", inTheLibraryPercent);
        }else{
            modelAndView.addObject("inTheLibraryPercent", 0);
        }

        Map<String, Object> borrowingQuantityMap = new HashMap<>();
        borrowingQuantityMap.put("name", "借阅数量");
        borrowingQuantityMap.put("value", inTheLibrary);
        overviewPieDataList.add(borrowingQuantityMap);
        if (borrowCount != 0 && !archivesList.isEmpty()) {
            BigDecimal borrowCountPercent = NumberUtil.round((double) borrowCount / archivesList.size() * 100, 2);
            modelAndView.addObject("borrowCountPercent", borrowCountPercent);
        }else{
            modelAndView.addObject("borrowCountPercent", 0);
        }
        modelAndView.addObject("overviewPieDataList", overviewPieDataList);
        // 档案出入库记录
        List<BorrowingRecords> borrowingRecordsList = borrowingRecordsMapper.selectList(new QueryWrapper<BorrowingRecords>()
                .orderByDesc("create_time").last("limit 6").eq("status",1));
        List<Map<String, Object>> borrowingList = new ArrayList<>();
        for (BorrowingRecords borrowingRecords : borrowingRecordsList) {
            Map<String, Object> borrowingMap = new HashMap<>();
            StringBuilder operationContent = new StringBuilder();
            String fileName = borrowingRecords.getFileName();
            if (borrowingRecords.getFileName().length() > 5) {
                fileName = fileName.substring(0, 5) + "...";
            }
            if (borrowingRecords.getDataStatus() == 1) {
                borrowingMap.put("operationType", 1);
                operationContent.append(borrowingRecords.getBorrowers()).append("借阅").append(fileName).append("档案");
            } else {
                borrowingMap.put("operationType", 2);
                operationContent.append(borrowingRecords.getBorrowers()).append("归还").append(fileName).append("档案");
            }
            borrowingMap.put("operationContent", operationContent.toString());
            borrowingMap.put("create_time", borrowingRecords.getCreateTime());
            borrowingList.add(borrowingMap);
        }
        modelAndView.addObject("borrowingList", borrowingList);
        // 档案出入库记录柱状图
        HttpSession session = request.getSession();
        String number = Convert.toStr(session.getAttribute("number"));
        List<BorrowingRecords> archivesRecordList = borrowingRecordsMapper.getInThePast6Months(number);
        Date nowDate = DateUtil.date();
        Date newDate = DateUtil.offset(nowDate, DateField.MONTH, -6);
        Map<String, Integer> lendingMap = new LinkedHashMap<String, Integer>() {
            {
                for (int i = 0; i <= 6; i++) {
                    Date offsetNewDate = DateUtil.offset(newDate, DateField.MONTH, i);
                    int year = DateUtil.year(offsetNewDate);
                    int month = DateUtil.month(offsetNewDate) + 1;
                    put(year + "-" + month + "月", 0);

                }
            }
        };
        Map<String, Integer> returnMap = new LinkedHashMap<String, Integer>() {
            {
                for (int i = 0; i <= 6; i++) {
                    Date offsetNewDate = DateUtil.offset(newDate, DateField.MONTH, i);
                    int year = DateUtil.year(offsetNewDate);
                    int month = DateUtil.month(offsetNewDate) + 1;
                    put(year + "-" + month + "月", 0);

                }
            }
        };
        List<Object> xName = new ArrayList<>(lendingMap.keySet());
        modelAndView.addObject("barChartxName", xName);
        for (BorrowingRecords borrowingRecords : archivesRecordList) {
            Date date = DateUtil.parse(borrowingRecords.getCreateTime(), "yyyy-MM-dd");
            int year = DateUtil.year(date);
            int month = DateUtil.month(date) + 1;
            if (borrowingRecords.getDataStatus() == 1) {
                int count = lendingMap.get(year + "-" + month + "月") + 1;
                lendingMap.put(year + "-" + month + "月", count);
            } else {
                int count = returnMap.get(year + "-" + month + "月") + 1;
                returnMap.put(year + "-" + month + "月", count);
            }
        }
        List<Object> lendingList = new ArrayList<>(lendingMap.values());
        modelAndView.addObject("barChartLendingList", lendingList);
        List<Object> returnList = new ArrayList<>(returnMap.values());
        modelAndView.addObject("barChartReturnList", returnList);
        // 设备状态
        Host host =hostService.getOne(new QueryWrapper<Host>().eq("number", number));
        modelAndView.addObject("host", host);
        // 日志信息
        return modelAndView;
    }

    /**
     * 主页入库折线图
     */
    @GetMapping("InsertFileLineChart")
    @ResponseBody
    public ResponseModel getInsertFileLineChart(@RequestParam(value = "selectStartDate", required = false) String selectStartDate,
                                                @RequestParam(value = "selectEndDate", required = false) String selectEndDate,
                                                HttpServletRequest request) throws ParseException {
        HttpSession session = request.getSession();
        String number = Convert.toStr(session.getAttribute("number"));
        List<Archives> archivesList = null;
        Date nowDate = DateUtil.date();
        Map<String, Integer> monthMap = null;
        if (StrUtil.isEmpty(selectStartDate) && StrUtil.isEmpty(selectEndDate)) {
            archivesList = archivesMapper.getInThePast6Months(number);
            Date newDate = DateUtil.offset(nowDate, DateField.MONTH, -6);
            monthMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= 6; i++) {
                        Date offsetNewDate = DateUtil.offset(newDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);
                    }
                }
            };
        } else {
            Date startDate = DateUtil.parse(selectStartDate, "yyyy-MM-dd");
            String formatStartDate = DateUtil.format(startDate, "yyyy-MM-dd");
            Date endDate = DateUtil.parse(selectEndDate, "yyyy-MM-dd");
            String formatEndDate = DateUtil.format(endDate, "yyyy-MM-dd");
            archivesList = archivesMapper.getSpecifyData(formatStartDate, formatEndDate, number);

            String format = DateUtil.format(nowDate, "yyyy-MM-dd");
            int monthDifference = CalculateMonth.getMonthSpace(selectStartDate, format);
            monthMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= monthDifference; i++) {
                        Date offsetNewDate = DateUtil.offset(startDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);
                    }
                }
            };
        }

        for (Archives archives : archivesList) {
            Date date = DateUtil.parse(archives.getEntryTime(), "yyyy-MM-dd");
            int year = DateUtil.year(date);
            int month = DateUtil.month(date) + 1;
            int count = monthMap.get(year + "-" + month + "月") + 1;
            monthMap.put(year + "-" + month + "月", count);
        }
        List<Object> xName = new ArrayList<>(monthMap.keySet());
        List<Object> yName = new ArrayList<>(monthMap.values());
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("xName", xName);
        returnMap.put("yName", yName);
        //饼图处理
        List<Map<String, Object>> pieChartData = new ArrayList<>();
        for (String key : monthMap.keySet()) {
            Map<String, Object> innerMap = new HashMap<>();
            innerMap.put("value", monthMap.get(key));
            innerMap.put("name", key);
            pieChartData.add(innerMap);
        }
        returnMap.put("pieChartData", pieChartData);
        return ResponseModel.success(returnMap);
    }

    /**
     * 主页取档和归档柱状图
     */
    @GetMapping("borrowingRecordHistogram")
    @ResponseBody
    public ResponseModel borrowingRecordsLineChart(@RequestParam(value = "selectStartDate", required = false) String selectStartDate,
                                                   @RequestParam(value = "selectEndDate", required = false) String selectEndDate,
                                                   HttpServletRequest request) throws ParseException {
        HttpSession session = request.getSession();
        String number = Convert.toStr(session.getAttribute("number"));
        List<BorrowingRecords> archivesRecordList = null;
        Date nowDate = DateUtil.date();
        Map<String, Integer> lendingMap = null;
        Map<String, Integer> returnMap = null;
        if (StrUtil.isEmpty(selectStartDate) && StrUtil.isEmpty(selectEndDate)) {
            archivesRecordList = borrowingRecordsMapper.getInThePast6Months(number);
            Date newDate = DateUtil.offset(nowDate, DateField.MONTH, -6);
            lendingMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= 6; i++) {
                        Date offsetNewDate = DateUtil.offset(newDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);

                    }
                }
            };
            returnMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= 6; i++) {
                        Date offsetNewDate = DateUtil.offset(newDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);

                    }
                }
            };
        } else {
            Date startDate = DateUtil.parse(selectStartDate, "yyyy-MM-dd");
            String formatStartDate = DateUtil.format(startDate, "yyyy-MM-dd");
            Date endDate = DateUtil.parse(selectEndDate, "yyyy-MM-dd");
            String formatEndDate = DateUtil.format(endDate, "yyyy-MM-dd");
            archivesRecordList = borrowingRecordsMapper.getSpecifyData(formatStartDate, formatEndDate, number);
            String format = DateUtil.format(nowDate, "yyyy-MM-dd");
            int monthDifference = CalculateMonth.getMonthSpace(selectStartDate, format);
            lendingMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= monthDifference; i++) {
                        Date offsetNewDate = DateUtil.offset(startDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);
                    }
                }
            };
            returnMap = new LinkedHashMap<String, Integer>() {
                {
                    for (int i = 0; i <= monthDifference; i++) {
                        Date offsetNewDate = DateUtil.offset(startDate, DateField.MONTH, i);
                        int year = DateUtil.year(offsetNewDate);
                        int month = DateUtil.month(offsetNewDate) + 1;
                        put(year + "-" + month + "月", 0);
                    }
                }
            };
        }
        for (BorrowingRecords borrowingRecords : archivesRecordList) {
            Date date = DateUtil.parse(borrowingRecords.getCreateTime(), "yyyy-MM-dd");
            int year = DateUtil.year(date);
            int month = DateUtil.month(date) + 1;
            if (borrowingRecords.getDataStatus() == 1) {
                int count = lendingMap.get(year + "-" + month + "月") + 1;
                lendingMap.put(year + "-" + month + "月", count);
            } else {
                int count = returnMap.get(year + "-" + month + "月") + 1;
                returnMap.put(year + "-" + month + "月", count);
            }
        }
        List<Object> xName = new ArrayList<>(lendingMap.keySet());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("xName", xName);
        List<Object> lendingList = new ArrayList<>(lendingMap.values());
        resultMap.put("lendingList", lendingList);
        List<Object> returnList = new ArrayList<>(returnMap.values());
        resultMap.put("returnList", returnList);
        //饼图处理
        List<Map<String, Object>> pieChartData = new ArrayList<>();
        for (String key : lendingMap.keySet()) {
            Map<String, Object> innerMap = new HashMap<>();
            innerMap.put("value", lendingMap.get(key));
            innerMap.put("name", key);
            pieChartData.add(innerMap);
        }
        resultMap.put("lendingPieChartData", pieChartData);
        //归档饼图处理
        List<Map<String, Object>> returnData = new ArrayList<>();
        for (String key : returnMap.keySet()) {
            Map<String, Object> innerMap = new HashMap<>();
            innerMap.put("value", returnMap.get(key));
            innerMap.put("name", key);
            returnData.add(innerMap);
        }
        resultMap.put("returnPieChartData", returnData);
        return ResponseModel.success(resultMap);
    }


    /**
     * 展示单个柜体数据
     */
    @GetMapping("host/info")
    public ModelAndView hostInfo(@RequestParam(value = "number") String number) {
        Date nowDate = DateUtil.date();
        int nowMonth = nowDate.getMonth() + 1;
        List<Archives> archivesList = archivesService.list(new QueryWrapper<Archives>().eq("number", number + "#"));
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("Console/hostInfo");
        int lendFileCount = 0;//在柜档案个数
        int returnFileCount = 0;//取出档案个数
        int nowMonthCount = 0;//本月新增档案数量
        for (Archives archives : archivesList) {
            if (archives.getStatus() == 0) {
                lendFileCount++;
            } else {
                returnFileCount++;
            }
            //本月新增档案数量
            Date date = DateUtil.parse(archives.getEntryTime());
            int month = date.getMonth() + 1;
            if (month == nowMonth) {
                nowMonthCount++;
            }
        }
        int nowMonthReturnFileCount = 0; //本月归档
        int nowMonthLedFileCount = 0; //本月取档
        List<BorrowingRecords> borrowingRecordsList = borrowingRecordsMapper.getNowMonthData(number + "#");
        for (BorrowingRecords borrowingRecords : borrowingRecordsList) {
            if (borrowingRecords.getDataStatus() == 1) {
                nowMonthLedFileCount++;
            } else {
                nowMonthReturnFileCount++;
            }
        }
        modelAndView.addObject("lendFileCount", lendFileCount);
        modelAndView.addObject("returnFileCount", returnFileCount);
        modelAndView.addObject("sumCount", archivesList.size());
        modelAndView.addObject("nowMonthCount", nowMonthCount);
        modelAndView.addObject("nowMonthReturnFileCount", nowMonthReturnFileCount);
        modelAndView.addObject("nowMonthLedFileCount", nowMonthLedFileCount);
        return modelAndView;

    }

    /**
     * 切换机柜
     */
    @PostMapping("/change/cabinet")
    @ResponseBody
    public ResponseModel changeCabinet(@RequestBody JSONObject data, HttpServletRequest request) {
        if (StrUtil.isEmpty(data.getStr("number"))) {
            return ResponseModel.fail("缺少参数");
        }
        Host host = hostService.getOne(new QueryWrapper<Host>().eq("number", data.getStr("number")));
        if (host != null) {
            HttpSession session = request.getSession();
            session.setAttribute("cabinet", host.getIp());
            session.setAttribute("number", host.getNumber());
            return ResponseModel.success("切换 " + host.getNumber() + " 柜体成功");
        } else {
            return ResponseModel.fail("未查到当前柜体编号");
        }
    }

    /**
     * 温湿度自动更新
     */
    @GetMapping("temperatureAndHumidity/update")
    @ResponseBody
    public ResponseModel temperatureAndHumidity(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String sendIpAddress = Convert.toStr(session.getAttribute("cabinet"));
        Map<String, Object> hostMap = hostService.getMap(new QueryWrapper<Host>().eq("ip", sendIpAddress).select("temperature",
                "temperature_upper", "humidity", "humidity_upper"));
        //请求温湿度更新
        sendCmd.send("GETTEMP:", request, null);
        return ResponseModel.success(hostMap);
    }
}
